package cn.org.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import cn.org.IDao.OrgMapper;
import cn.org.domain.Org;
import cn.org.domain.Person;
import cn.org.dto.TreeDto;
import cn.org.service.IOrgService;
import cn.org.utils.BasicSysKit;

@Service("orgService")
public class OrgServiceImpl implements IOrgService {
	@Resource
	private OrgMapper orgDao;

	@Override
	public int deleteByPrimaryKey(Integer id) {
		return orgDao.deleteByPrimaryKey(id);
	}

	@Override
	public int insert(Org record) {
		
		return orgDao.insert(record);
	}

	@Override
	public int insertSelective(Org record) {
		
		return orgDao.insertSelective(record);
	}

	@Override
	public Org selectByPrimaryKey(Integer id) {
		
		return orgDao.selectByPrimaryKey(id);
	}

	@Override
	public int updateByPrimaryKeySelective(Org record) {
		
		return orgDao.updateByPrimaryKeySelective(record);
	}

	@Override
	public int updateByPrimaryKey(Org record) {
		
		return orgDao.updateByPrimaryKey(record);
	}

	@Override
	public List<Org> getAllChildOrg(Org org) {
		return orgDao.getAllChildOrg(org);
	}
	@Override
	public List<TreeDto> listChildTreeByOrg(Org org) {
		List<Org> orgs = getAllChildOrg(org);
		return orgs2Trees(orgs);
	}
	
	private List<TreeDto> orgs2Trees(List<Org> orgs) {
		List<TreeDto> tds = new ArrayList<TreeDto>();
		TreeDto td = null;
		for(Org org:orgs) {
			if(!BasicSysKit.isEmpty(org.getPid())) {
				td = new TreeDto(org.getId(), org.getName(),org.getPid());
			} else {
				td = new TreeDto(org.getId(),org.getName(),-1);
			}
			tds.add(td);
		}
		return tds;
	}

	/**
	 * 通过几个ids获取相应的组织机构的节点
	 * @param ids
	 * @return
	 */
	private List<Org> listChildOrgByIds(List<Integer> ids) {
		List<Org> orgs = listAllOrg();
		Map<Integer,List<Org>> corgs = org2map(orgs);
		List<Org> rorgs = new ArrayList<Org>();
		for(Integer id:ids) {
			rorgs.add(orgDao.selectByPrimaryKey(id));
			getOrgByMap(corgs,id,rorgs);
		}
		return rorgs;
	}

	@Override
	public List<TreeDto> listChildTreeByOrgs(List<Integer> ids) {
		List<Org> orgs = this.listChildOrgByIds(ids);
		return orgs2Trees(orgs);
	}

	@Override
	public List<Integer> listChildIdsByOrg(int id) {
		/*
		 * 获取某个组织机构下面的所有组织的子节点，通常使用的是递归，使用递归会反复的查询数据库，效率不高
		 * 可以考虑使用map来替代反复查询数据库的递归操作。
		 */
		//1、取出所有的数据
		List<Org> orgs = listAllOrg();
		//2、格式化为一个map
		Map<Integer,List<Org>> corgs = org2map(orgs);
		//3、通过map来获取所有的子节点数据
		List<Org> rorgs = new ArrayList<Org>();
		rorgs.add(orgDao.selectByPrimaryKey(id));
		getOrgByMap(corgs,id,rorgs);
		List<Integer> orgIds = orgs2OrgIds(rorgs);
		return orgIds;
	}
	
	private List<Integer> orgs2OrgIds(List<Org> orgs) {
		List<Integer> orgIds = new ArrayList<Integer>();
		for(Org to:orgs) {
			orgIds.add(to.getId());
		}
		return orgIds;
	}
	
	private List<Org> listAllOrg() {
		List<Org> orgs = orgDao.getAllOrg();
		return orgs;
	}
	
	private void getOrgByMap(Map<Integer,List<Org>> orgs,int id,List<Org> corgs) {
		if(!orgs.containsKey(id)) return;
		List<Org> torgs = orgs.get(id);
		for(Org o:torgs) {
			corgs.add(o);
			//org的子节点中如果还是orgs的key，就说明该子节点中依然是某个父节点，此时就通过递归获取数据
			if(orgs.containsKey(o.getId())) {
				getOrgByMap(orgs,o.getId(),corgs);
			}
		}
	}

	private Map<Integer, List<Org>> org2map(List<Org> orgs) {
		Map<Integer,List<Org>> maps = new HashMap<Integer,List<Org>>();
		List<Org> os = null;
		for(Org o:orgs ) {
			if(o.getPid()==null) {
				os = new ArrayList<Org>();
				maps.put(o.getId(), os);
			} else {
				if(maps.containsKey(o.getPid())) {
					maps.get(o.getPid()).add(o);
				} else {
					os = new ArrayList<Org>();
					if(!os.contains(o))
						os.add(o);
					maps.put(o.getPid(), os);
				}
			}
		}
		return maps;
	}

	@Override
	public List<Org> getOrgByPerson( Person person) {
		return orgDao.getOrgByPerson(person.getId());
	}

	@Override
	public Org selectByName(String name) {
		
		return orgDao.selectByName(name);
	}
}
